import { Collapse } from 'antd';
import classNames from 'classnames';
import React from 'react';

import { LayerInfoFE } from '@/pages/TemplateEditor/interface';

import { LayerTypeBE } from '../../../../../constant';
import { DeepPartial } from '../../../../../interface';
import { getOpacityByData } from '../../../../../utils';
import containerStyles from '../index.module.less';
import Header from './components/Header';
import LayerConfigs from './components/LayerConfigs';
import styles from './index.module.less';

const { Panel } = Collapse;

interface Props {
  index: number;
  layer: LayerInfoFE;
  screenSize: string;
  disableNewLayer: boolean;
  disableProductLayer: boolean;
  onUpdate: (
    index: number,
    data: LayerInfoFE,
    needUpdateForm?: boolean,
    needRerenderScreen?: boolean
  ) => void;
  onCopy: (index: number) => void;
  onRemove: (index: number) => void;
  onSetCropLayerId: (id: string) => void;
}

const Layer = ({
  index,
  layer,
  screenSize,
  disableNewLayer,
  disableProductLayer,
  onUpdate,
  onCopy,
  onRemove,
  onSetCropLayerId,
  ...restProps
}: Props): JSX.Element => {
  const handleNameChange = (name: string): void => {
    onUpdate(index, {
      ...layer,
      data: {
        ...layer.data,
        name
      }
    });
  };

  const handleCopy = (): void => {
    onCopy(index);
  };

  const handleRemove = (e): void => {
    e.stopPropagation();
    onRemove(index);
  };

  const handleToggleHide = (): void => {
    const { data: oldData } = layer;
    const newIsHidden = !oldData.isHidden;

    const newData = {
      ...oldData,
      isHidden: newIsHidden,
      needPreview: oldData.type === LayerTypeBE.Text // 当text变为可见的时候，需要重新调用realtime preview
    };

    const newLayer = {
      ...layer,
      opacity: getOpacityByData(newData),
      data: newData
    };

    onUpdate(index, newLayer);
  };

  const handleConfigChange = async (
    newLayer: DeepPartial<LayerInfoFE>,
    needUpdateForm = false,
    needRerenderScreen = false
  ): Promise<void> => {
    const { data } = newLayer;
    const {
      text = {} as any,
      image = {} as any,
      graphics = {} as any
    } = data || {};

    const { data: oldData } = layer;
    const {
      text: oldText = {},
      image: oldImage = {},
      graphics: oldGraphics = {}
    } = oldData;

    const updateData = {
      ...oldData,
      ...(data as any),
      text: {
        ...oldText,
        ...text
      },
      image: {
        ...oldImage,
        ...image
      },
      graphics: {
        ...oldGraphics,
        ...graphics
      }
    };

    onUpdate(
      index,
      {
        ...layer,
        ...newLayer,
        opacity: getOpacityByData(updateData),
        data: updateData
      },
      needUpdateForm,
      needRerenderScreen
    );
  };

  return (
    <Panel
      {...restProps}
      className={classNames(styles.layer, containerStyles['drag-row'])}
      key={layer.data.id}
      header={
        <Header
          layer={layer}
          canCopy={
            !disableNewLayer &&
            !(disableProductLayer && layer.data.type === LayerTypeBE.Product)
          }
          onCopy={handleCopy}
          onRemove={handleRemove}
          onChangeName={handleNameChange}
          onToggleHide={handleToggleHide}
        />
      }
    >
      <LayerConfigs
        index={index}
        layerData={layer}
        screenSize={screenSize}
        onChange={handleConfigChange}
        onSetCropLayerId={onSetCropLayerId}
      />
    </Panel>
  );
};

export default Layer;
